#include "glad/glad.h"
#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/quaternion_geometric.hpp>
#include <glm/fwd.hpp>
#include <glm/geometric.hpp>
#include <math.h>
#include "shader.h"
#include "texture.h"
#include "matrix.h"

//#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <iostream>
#include "ylogger.h"

void createTexture(unsigned int* texture);

void framebuffer_size_callback(GLFWwindow*, int, int);

int main(int argc, char** argv)
{
    /*
    glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
    glm::vec3 cameraDirection = glm::normalize(glm::vec3(0.0f, 0.0f, 3.0f) - glm::vec3(0.0f, 0.0f, 0.0f));
    
    glm::vec3 carmeaRight = glm::normalize(glm::cross(cameraDirection, up));
    for(int i = 0;i < 3; i++)
    {
        std::cout << carmeaRight[i] <<" ";
    }
    std::cout <<std::endl;
    */

    glm::mat4 view1 = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

    for(int i = 0;i < 4; i ++)
    {
        for(int j = 0;j < 4; j++)
        {
        }
        std::cout << std::endl;
    }

    return 0;
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* win = glfwCreateWindow(800, 600, "LearnOpenGL", nullptr, nullptr);
    if(!win)
    {
        return -1;
    }
    glfwMakeContextCurrent(win);
    glfwSetFramebufferSizeCallback(win,framebuffer_size_callback);
    
    if(!gladLoadGLLoader((GLADloadproc)(glfwGetProcAddress)))
    {
        return -1;
    }
    Shader shader("shader/vertex.glsl", "shader/fragment.glsl");
    /*
    GLfloat vertices[] = {
        -1.0f, -1.0f, 0.0f, 0.0, 0.0f, 1.0f, 0.0f, 0.0f,
        1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f
    };
    */
    /*  
    GLfloat vertices[] = {
        -1.0f, -1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f, 0.0f,
        1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
        -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
    };
    */
    GLfloat vertices[] = {
        -0.5f, -0.5f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f, 0.0f,
        0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
        -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f
    };
    GLuint indeces[] = {
        0,1,3,
        1,2,3
    };
    GLuint VBO, VAO, EBO, texture, texture2;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    glBindVertexArray(VAO);
    //绑定顶点坐标
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat), (void*)0);
    glEnableVertexAttribArray(0);
    
    //绑定索引
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indeces), indeces, GL_STATIC_DRAW);

    //绑定纹理坐标
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat),(void*)(3*sizeof(float)));
    glEnableVertexAttribArray(1);
    //榜第嗯颜色坐标
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8*sizeof(GLfloat),(void*)(5*sizeof(float)));
    glEnableVertexAttribArray(2);
    
    //生成纹理
    glGenTextures(1, &texture);
   // glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int with, height, nrChannels;
    stbi_set_flip_vertically_on_load(true);
    unsigned char* data = stbi_load("res/xuying-11.jpg", &with, &height, &nrChannels, 0);
//    glfwSetWindowSize(win, with, height);
    if(data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, with, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    stbi_image_free(data);


  //生成纹理
    glGenTextures(1, &texture2);
   // glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture2);

    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

 //   stbi_set_flip_vertically_on_load(true);
    data = stbi_load("res/wall.jpg", &with, &height, &nrChannels, 0);
//    glfwSetWindowSize(win, with, height);
    if(data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, with, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    stbi_image_free(data);
   


    shader.use();
    shader.setInt("texture1", 0);
    shader.setInt("texture2", 1);
    //

  //  createTexture(&texture);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glm::mat4 model(1.0f);
    model = glm::rotate(model, glm::radians(-45.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    glm::mat4 view(1.0f);
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
    glm::mat4 project(1.0f);
    project = glm::perspective(glm::radians(45.0f), (float)800/600, 0.1f, 100.0f);
    while(!glfwWindowShouldClose(win))
    {
        if(glfwGetKey(win, GLFW_KEY_ESCAPE) == GLFW_KEY_ENTER)
        {
            glfwSetWindowShouldClose(win, true);
        }
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);

        
       
        shader.use();
      //  GLuint transformLoc = glGetUniformLocation(shader.Id(), "transform");
      //  glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model));

        GLuint transformLoc = glGetUniformLocation(shader.Id(), "modelMat");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model));

        transformLoc = glGetUniformLocation(shader.Id(), "viewMat");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(view));

        transformLoc = glGetUniformLocation(shader.Id(), "projectMat");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(project));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glfwSwapBuffers(win);
        glfwPollEvents();
    }
    glfwDestroyWindow(win);
    glfwTerminate();
    return 0;
}

void framebuffer_size_callback(GLFWwindow* win, int width, int height)
{
    glViewport(0, 0, width, height);
}

void createTexture(unsigned int* texture)
{
    glGenTextures(1, texture);
    glBindTexture(GL_TEXTURE_2D, *texture);

    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int with, height, nrChannels;
    unsigned char* data = stbi_load("res/test.png", &with, &height, &nrChannels, 0);
    if(data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, with, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    stbi_image_free(data);
}


